package com.dzqc.fly.common;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONFunction;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.regexp.RegexpUtils;
import net.sf.json.util.CycleDetectionStrategy;
import net.sf.json.util.JSONUtils;

/**
 * 类名称: JsonUtil
 * 类描述: Json格式化工具
 * 创建人: tonghl
 * 创建时间: 2022年06月29日 上午11:01:05
 * @version v1.0.0
 *
 */
public abstract class JsonUtil {

    /** Constant for char " */
    public static final String DOUBLE_QUOTE = "\"";
    /** Constant for char ' */
    public static final String SINGLE_QUOTE = "'";

    private static final String FUNCTION_PATTERN = "^function[ ]?\\(.*?\\)[ \n\t]*\\{.*?\\}$";
    private static final String FUNCTION_PREFIX = "function";


    /**
     *
     * json转为bean
     * @param jsonString
     * @return
     */
    public static Object jsonStr2Bean(String jsonString, Class beanClass) {
        Object bean;
        JSONObject jsonObject = JSONObject.fromObject(jsonString);
        bean = JSONObject.toBean(jsonObject, beanClass);
        return bean;
    }



    /**
     *
     * json字符串转为bean
     * @param jsonString
     * @return
     */
    public static Object jsonStrWithDate2Bean(String jsonString, Class beanClass) {
        Object bean;
        JSONObject jsonObject = JSONObject.fromObject(jsonString);
        String[] dateFormats = new String[] {"yyyy/MM/dd"};

        JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));
        bean = JSONObject.toBean(jsonObject, beanClass);
        return bean;

    }

    /**
     *
     * json转为list
     * @param jsonString
     * @return
     */
    public static List jsonStr2List(String jsonString, Class beanClass){
        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        JSONObject jsonObject;
        List list = new ArrayList();
        for ( int i = 0 ; i<jsonArray.size(); i++){
            jsonObject = jsonArray.getJSONObject(i);
            Iterator iter = jsonObject.keys();
            Map map= new HashMap();
            while (iter.hasNext()) {
                String sKey = (String) iter.next().toString();
                String sValue = jsonObject.get(sKey).toString();
                map.put(sKey, sValue);
            }

            list.add(map);
        }
        return list;
    }

    /**
     *
     * json转为bject对象
     * @param jsonString
     * @return
     */
    public static Object[] jsonStr2Array(String jsonString) {
        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        return jsonArray.toArray();

    }

    /**
     *
     * json转为String数组
     * @param jsonString
     * @return
     */
    public static String[] jsonStr2StringArray(String jsonString) {

        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        String[] stringArray = new String[jsonArray.size()];
        for (int i = 0; i < jsonArray.size(); i++) {
            stringArray[i] = jsonArray.getString(i);
        }
        return stringArray;
    }

    /**
     *
     * json转为Integer数组
     * @param jsonString
     * @return
     */
    public static Integer[] jsonStr2IntgerArray(String jsonString) {

        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        Integer[] integerArray = new Integer[jsonArray.size()];
        for (int i = 0; i < jsonArray.size(); i++) {
            integerArray[i] = jsonArray.getInt(i);

        }
        return integerArray;
    }

    /**
     *
     * json转为long数组
     * @param jsonString
     * @return
     */
    public static Long[] jsonStr2LongArray (String jsonString) {

        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        Long[] longArray = new Long[jsonArray.size()];
        for (int i = 0; i < jsonArray.size(); i++) {
            longArray[i] = jsonArray.getLong(i);

        }
        return longArray;
    }

    /**
     *
     * json转为ouble数组
     * @param jsonString
     * @return
     */
    public static Double[] jsonStr2DoubleArray (String jsonString) {

        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        Double[] doubleArray = new Double[jsonArray.size()];
        for (int i = 0; i < jsonArray.size(); i++) {
            doubleArray[i] = jsonArray.getDouble(i);

        }
        return doubleArray;
    }


    /**
     *
     * json转为bean
     * @return
     */
    public static Object json2Bean(JSONObject aJson, Class beanClass) {
        Object bean;
        bean = JSONObject.toBean(aJson, beanClass);
        return bean;
    }

    /**
     *
     * json转为map
     * @return
     */
    public static Map json2Map(JSONObject json) {

        Iterator iter = json.keys();
        String sKey;
        String sValue;
        Map map = new HashMap();
        while (iter.hasNext()) {
            sKey = (String) iter.next().toString();
            sValue = json.get(sKey).toString();
            map.put(sKey, sValue);
        }
        return map;
    }

    /**
     *
     * json转为list
     * @return
     */
    public static List json2List(JSONArray jsonArray){

        JSONObject jsonObject;
        List list = new ArrayList();
        for ( int i = 0 ; i<jsonArray.size(); i++){
            jsonObject = jsonArray.getJSONObject(i);
            Iterator iter = jsonObject.keys();
            Map map= new HashMap();
            while (iter.hasNext()) {
                String sKey = (String) iter.next().toString();
                String sValue = jsonObject.get(sKey).toString();
                map.put(sKey, sValue);
            }

            list.add(map);
        }
        return list;
    }


    /**************Object to json ****************/

    /**
     * @param javaObj
     * @return
     */
    public static String  bean2JosnStr(Object javaObj) {

        JSONObject json;
        json = JSONObject.fromObject(javaObj);
        return json.toString();

    }

    /**
     * @param javaObj
     * @param dataFormat
     * @return
     */
    public static String bean2JosnStr(Object javaObj,
                                      String dataFormat) {

        JSONObject json;
        JsonConfig jsonConfig = configJson(dataFormat);
        json = JSONObject.fromObject(javaObj, jsonConfig);
        return json.toString();

    }


    public static String map2jsonStr(Map aMap) {

        JSONObject json = JSONObject.fromObject(aMap);
        return json.toString();

    }

    /**
     * Tests if obj is javaScript function.<br>
     * Obj must be a non-null String and match <nowrap>"^function[ ]?\\(.*\\)[
     * ]?\\{.*\\}$"</nowrap>
     */
    public static boolean isFunction( Object obj ) {
        if( obj instanceof String ){
            String str = (String) obj;
            return str.startsWith( FUNCTION_PREFIX ) && RegexpUtils.getMatcher( FUNCTION_PATTERN ).matches( str );
        }
        if( obj instanceof JSONFunction ){
            return true;
        }
        return false;
    }

    /**
     * Produce a string in double quotes with backslash sequences in all the
     * right places. A backslash will be inserted within </, allowing JSON text
     * to be delivered in HTML. In JSON text, a string cannot contain a control
     * character or an unescaped quote or backslash.<br>
     * <strong>CAUTION:</strong> if <code>string</code> represents a
     * javascript function, translation of characters will not take place. This
     * will produce a non-conformant JSON text.
     *
     * @param string A String
     * @return A String correctly formatted for insertion in a JSON text.
     */
    public static String quote( String string ) {
        if( isFunction( string ) ) {
            return string;
        }
        if( string == null || string.length() == 0 ) {
            return "";
        }

        char b;
        char c = 0;
        int i;
        int len = string.length();
        StringBuffer sb = new StringBuffer( len * 2 );
        String t;
        char[] chars = string.toCharArray();
        char[] buffer = new char[1030];
        int bufferIndex = 0;
        for( i = 0; i < len; i += 1 ) {
            if( bufferIndex > 1024 ) {
                sb.append( buffer, 0, bufferIndex );
                bufferIndex = 0;
            }
            b = c;
            c = chars[i];
            switch( c ) {
                case '\\':
                case '"':
                    buffer[bufferIndex++] = '\\';
                    buffer[bufferIndex++] = c;
                    break;
                case '/':
                    if( b == '<' ) {
                        buffer[bufferIndex++] = '\\';
                    }
                    buffer[bufferIndex++] = c;
                    break;
                default:
                    if( c < ' ' ) {
                        switch( c ) {
                            case '\b':
                                buffer[bufferIndex++] = '\\';
                                buffer[bufferIndex++] = 'b';
                                break;
                            case '\t':
                                buffer[bufferIndex++] = '\\';
                                buffer[bufferIndex++] = 't';
                                break;
                            case '\n':
                                buffer[bufferIndex++] = '\\';
                                buffer[bufferIndex++] = 'n';
                                break;
                            case '\f':
                                buffer[bufferIndex++] = '\\';
                                buffer[bufferIndex++] = 'f';
                                break;
                            case '\r':
                                buffer[bufferIndex++] = '\\';
                                buffer[bufferIndex++] = 'r';
                                break;
                            default:
                                t = "000" + Integer.toHexString( c );
                                int tLength = t.length();
                                buffer[bufferIndex++] = '\\';
                                buffer[bufferIndex++] = 'u';
                                buffer[bufferIndex++] = t.charAt( tLength - 4 );
                                buffer[bufferIndex++] = t.charAt( tLength - 3 );
                                buffer[bufferIndex++] = t.charAt( tLength - 2 );
                                buffer[bufferIndex++] = t.charAt( tLength - 1 );
                        }
                    } else {
                        buffer[bufferIndex++] = c;
                    }
            }
        }
        sb.append( buffer, 0, bufferIndex );
        return sb.toString();
    }


    public static JSONObject map2json(Map aMap){
        JSONObject json = JSONObject.fromObject(aMap);
        return json;
    }



    public static String list2jsonStr(List aList) {

        JSONArray jsonArray = JSONArray.fromObject(aList);
        return jsonArray.toString();

    }

    public static JSONArray list2json(List aList) {

        JSONArray jsonArray = JSONArray.fromObject(aList);
        return jsonArray;

    }

    /**
     *
     *
     * @return
     */
    public static String array2jsonStr(String[] aStr) {

        JSONArray jsonArray = JSONArray.fromObject(aStr);
        return jsonArray.toString();

    }

    public static JSONArray array2json(String[] aStr) {

        JSONArray jsonArray = JSONArray.fromObject(aStr);
        return jsonArray;

    }

    public static String array2jsonStr(Object aObject) {
        Class type = aObject.getClass();
        JSONArray jsonArray=null;
        if(type.isArray()){
            jsonArray = JSONArray.fromObject(aObject);
        }

        return jsonArray.toString();

    }



    /**
     *
     *
     * @param datePattern
     * @return
     */
    public static JsonConfig configJson(String datePattern) {
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setExcludes(new String[] { "" });
        jsonConfig.setIgnoreDefaultExcludes(false);
        jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
        jsonConfig.registerJsonValueProcessor(Date.class,
                new JsonDateProcessor(datePattern));

        return jsonConfig;
    }

    /**
     *
     * @param excludes
     * @param datePattern
     * @return
     */
    public static JsonConfig configJson(String[] excludes, String datePattern) {
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setExcludes(excludes);
        jsonConfig.setIgnoreDefaultExcludes(true);
        jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
        jsonConfig.registerJsonValueProcessor(Date.class,
                new JsonDateProcessor(datePattern));

        return jsonConfig;
    }


    /**
     * @param args
     */
    public static void main(String[] args) {

        String json = "[{testid=1,testname:\"sss\",testdesc:\"dfadsf\"},{testid=2,testname:\"gggg\",testdesc:\"jjjj\"}]";
		/*Test aTest= new Test();
		List aList = null;
		aList = JsonUtil.getList4Json(json,aTest.getClass());

		for(int i=0;i<aList.size();i++){
			aTest=(Test)aList.get(i);
			System.out.print(aTest.getTestdesc());
		}*/
		/*ApplicationContext context=new ClassPathXmlApplicationContext("resource/applicationContext.xml");
	      TestDaoImp testDao =(TestDaoImp)
	      context
			.getBean("testDao");
		List aList = testDao.getResultList();
		System.out.println(JsonUtil.list2json(aList));*/
        String[] s = {"a","b","c"};

        System.out.println(JsonUtil.array2json(s));
    }

}

